<template>
  <div class="scatter-chart-container">
    <div class="loading" v-if="isLoading">
      <span class="loading-text">散点图加载中...</span>
    </div>
    <div class="error" v-if="isError">
      <span class="error-text">图表加载失败，请刷新重试</span>
    </div>
    <div id="scatterChart" ref="chartDom" class="chart-content"></div>
  </div>
</template>

<script setup>
import { onMounted, ref, onBeforeUnmount, nextTick } from 'vue';
import * as echarts from 'echarts/core';
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent
} from 'echarts/components';
import { ScatterChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
// 导入 JSON 数据文件
import scatterData from '@/data/scatterChartData.json'

// 注册必要的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  ScatterChart,
  CanvasRenderer
]);

const chartDom = ref(null);
let myChart = null;
const isLoading = ref(true);
const isError = ref(false);

// 科技感颜色配置
const colorPalette = {
  primary: '#00eaff',
  secondary: '#87cefa',
  tertiary: '#ff6b9d',
  background: 'rgba(0, 10, 30, 0.3)',
  grid: 'rgba(0, 255, 255, 0.1)',
  axis: '#00eaff'
};

const getAdaptiveOption = (containerWidth, containerHeight) => {
  // 根据容器尺寸计算自适应参数
  const isMobile = containerWidth < 768;
  const isTablet = containerWidth >= 768 && containerWidth < 1024;
  
  // 基础缩放比例
  const scale = Math.min(containerWidth / 600, containerHeight / 400) || 1;
  
  // 动态调整字体和尺寸
  const titleFontSize = isMobile ? 14 : Math.max(14, 16 * scale);
  const labelFontSize = isMobile ? 10 : Math.max(10, 12 * scale);
  const axisFontSize = isMobile ? 9 : Math.max(9, 11 * scale);
  
  // 动态调整布局参数
  const gridLeft = isMobile ? '12%' : '10%';
  const gridRight = isMobile ? '12%' : '10%';
  const gridTop = isMobile ? '15%' : '12%';
  const gridBottom = isMobile ? '15%' : '12%';

  return {
    backgroundColor: 'transparent',
    title: {
      text: scatterData.chartConfig.title, // 从 JSON 读取标题
      subtext: scatterData.chartConfig.subTitle, // 从 JSON 读取副标题
      left: 'center',
      top: isMobile ? '5px' : '10px',
      textStyle: {
        color: colorPalette.primary,
        fontSize: titleFontSize,
        fontWeight: 'bold',
        textShadow: '0 0 10px rgba(0, 255, 255, 0.5)'
      },
      subtextStyle: {
        color: colorPalette.secondary,
        fontSize: Math.max(9, labelFontSize - 2)
      }
    },
    tooltip: {
      trigger: 'item',
      backgroundColor: 'rgba(0, 10, 30, 0.9)',
      borderColor: colorPalette.primary,
      borderWidth: 1,
      textStyle: {
        color: '#fff',
        fontSize: Math.max(9, labelFontSize - 2)
      },
      formatter: function (params) {
        return `
          <div style="text-align: left; font-size: ${Math.max(9, labelFontSize - 2)}px;">
            <div style="color: ${colorPalette.primary}; margin-bottom: 4px; font-weight: bold;">数据点 ${params.dataIndex + 1}</div>
            <div>X: ${params.value[0].toFixed(2)}</div>
            <div>Y: ${params.value[1].toFixed(2)}</div>
          </div>
        `;
      }
    },
    grid: {
      left: gridLeft,
      right: gridRight,
      bottom: gridBottom,
      top: gridTop,
      containLabel: true,
      backgroundColor: colorPalette.background,
      borderColor: 'rgba(0, 255, 255, 0.2)'
    },
    xAxis: {
      type: 'value',
      name: scatterData.chartConfig.xAxisName, // 从 JSON 读取 X 轴名称
      nameLocation: 'middle',
      nameGap: isMobile ? 20 : 25,
      nameTextStyle: {
        color: colorPalette.primary,
        fontSize: axisFontSize,
        fontWeight: 'bold'
      },
      axisLine: {
        lineStyle: {
          color: colorPalette.axis,
          width: 1
        }
      },
      axisTick: {
        lineStyle: {
          color: colorPalette.axis,
          width: 1
        },
        length: 4
      },
      axisLabel: {
        color: colorPalette.primary,
        fontSize: Math.max(8, axisFontSize - 1),
        margin: 8
      },
      splitLine: {
        lineStyle: {
          color: colorPalette.grid,
          type: 'dashed',
          width: 0.5
        }
      },
      min: scatterData.chartConfig.axisRange.xMin, // 从 JSON 读取 X 轴最小值
      max: scatterData.chartConfig.axisRange.xMax  // 从 JSON 读取 X 轴最大值
    },
    yAxis: {
      type: 'value',
      name: scatterData.chartConfig.yAxisName, // 从 JSON 读取 Y 轴名称
      nameLocation: 'end',
      nameGap: isMobile ? 10 : 15,
      nameTextStyle: {
        color: colorPalette.primary,
        fontSize: axisFontSize,
        fontWeight: 'bold'
      },
      axisLine: {
        lineStyle: {
          color: colorPalette.axis,
          width: 1
        }
      },
      axisTick: {
        lineStyle: {
          color: colorPalette.axis,
          width: 1
        },
        length: 4
      },
      axisLabel: {
        color: colorPalette.primary,
        fontSize: Math.max(8, axisFontSize - 1),
        margin: 8
      },
      splitLine: {
        lineStyle: {
          color: colorPalette.grid,
          type: 'dashed',
          width: 0.5
        }
      },
      min: scatterData.chartConfig.axisRange.yMin, // 从 JSON 读取 Y 轴最小值
      max: scatterData.chartConfig.axisRange.yMax  // 从 JSON 读取 Y 轴最大值
    },
    series: [
      {
        name: '数据分布',
        type: 'scatter',
        data: scatterData.sourceData, // 从 JSON 读取散点图核心数据
        symbolSize: function (data) {
          const baseSize = isMobile ? 4 : 6;
          return Math.min(Math.max(Math.sqrt(data[1]) * 1.5 + baseSize, baseSize), baseSize + 7);
        },
        itemStyle: {
          color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [
            {
              offset: 0,
              color: colorPalette.primary
            },
            {
              offset: 1,
              color: colorPalette.secondary
            }
          ]),
          borderColor: '#fff',
          borderWidth: 0.5,
          shadowBlur: isMobile ? 3 : 5,
          shadowColor: 'rgba(0, 255, 255, 0.3)'
        },
        emphasis: {
          scale: true,
          scaleSize: isMobile ? 1.2 : 1.3,
          itemStyle: {
            shadowBlur: isMobile ? 6 : 10,
            shadowColor: 'rgba(0, 255, 255, 0.5)',
            borderWidth: 1
          }
        },
        animation: true,
        animationDuration: 1000,
        animationEasing: 'elasticOut',
        animationDelay: function (idx) {
          return idx * 30;
        }
      }
    ],
    visualMap: isMobile ? undefined : { // 移动端隐藏视觉映射
      type: 'continuous',
      dimension: scatterData.chartConfig.visualMap.dimension, // 从 JSON 读取维度
      min: scatterData.chartConfig.visualMap.min, // 从 JSON 读取最小值
      max: scatterData.chartConfig.visualMap.max, // 从 JSON 读取最大值
      calculable: true,
      orient: 'vertical',
      right: '3%',
      top: '25%',
      height: '35%',
      textStyle: {
        color: colorPalette.primary,
        fontSize: Math.max(8, axisFontSize - 2)
      },
      inRange: {
        color: [colorPalette.secondary, colorPalette.primary, colorPalette.tertiary]
      }
    }
  };
};

const initChart = () => {
  if (!chartDom.value) {
    console.error('chartDom is not correctly referenced');
    isError.value = true;
    isLoading.value = false;
    return;
  }

  try {
    myChart = echarts.init(chartDom.value);
    
    // 获取容器尺寸
    const containerWidth = chartDom.value.clientWidth;
    const containerHeight = chartDom.value.clientHeight;
    
    // 使用自适应配置
    const option = getAdaptiveOption(containerWidth, containerHeight);
    myChart.setOption(option);
    
    // 添加窗口resize监听
    const handleResize = () => {
      if (myChart && chartDom.value) {
        const { clientWidth, clientHeight } = chartDom.value;
        const newOption = getAdaptiveOption(clientWidth, clientHeight);
        myChart.setOption(newOption);
        myChart.resize();
      }
    };
    
    window.addEventListener('resize', handleResize);
    
    onBeforeUnmount(() => {
      window.removeEventListener('resize', handleResize);
      if (myChart) {
        myChart.dispose();
      }
    });

    isLoading.value = false;
  } catch (error) {
    console.error('图表初始化失败:', error);
    isLoading.value = false;
    isError.value = true;
  }
};

onMounted(() => {
  nextTick(() => {
    initChart();
  });
});
</script>

<style scoped>
.scatter-chart-container {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.chart-content {
  width: 100%;
  height: 100%;
  min-height: 300px; /* 确保最小高度 */
  flex: 1;
  overflow: hidden;
}

/* 确保在移动端有足够的最小高度 */
@media (max-width: 768px) {
  .chart-content {
    min-height: 250px;
  }
}

.loading {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 10, 30, 0.3);
  border-radius: 8px;
  backdrop-filter: blur(4px);
  z-index: 2;
}

.loading-text {
  font-size: 16px;
  color: #00eaff;
  text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
  letter-spacing: 2px;
  animation: flash 1.5s infinite alternate;
}

.error {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(30, 0, 0, 0.3);
  border-radius: 8px;
  backdrop-filter: blur(4px);
  z-index: 2;
}

.error-text {
  font-size: 16px;
  color: #ff4d4f;
  text-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
  letter-spacing: 2px;
}

@keyframes flash {
  from { opacity: 0.6; }
  to { opacity: 1; }
}
</style>